import { useEffect, useMemo, useState } from "react";
import { FBXLoader } from "three/examples/jsm/loaders/FBXLoader.js";
import { GLTF, GLTFLoader } from "three/examples/jsm/loaders/GLTFLoader.js";
import { OBJLoader } from "three/examples/jsm/loaders/OBJLoader.js";
import { Object3D } from "three";

/**
 * 自定义钩子函数，用于加载模型
 * @param path - 模型加载路径
 * @returns {Object3D | null} - 加载的模型对象或 null
 */
export function useModelLoader(path: string): Object3D | null {
  const [model, setModel] = useState<Object3D | null>(null);

  // 使用 useMemo 缓存加载器实例
  const loader = useMemo(() => getLoaderForPath(path), [path]);

  useEffect(() => {
    if (!loader) {
      setModel(null);
      console.error("无法加载模型，未知的模型类型");
      return;
    }

    loader.load(
      path,
      (loadedModel) => {
        let object3D: Object3D | null = null;

        // 对于 GLTFLoader，提取第一个场景
        if (loader instanceof GLTFLoader) {
          object3D = (loadedModel as GLTF).scene; // 提取第一个场景作为 Object3D
        } else {
          object3D = loadedModel as Object3D; // 其他加载器直接使用加载的模型
        }
        setModel(object3D);
      },
      undefined,
      (error) => {
        console.error("模型加载失败:", error);
        setModel(null);
      }
    );

    // 清理函数以避免内存泄漏
    return () => {
      if (loader.manager) loader.manager.onLoad = () => {};
    };
  }, [loader, path]);

  function getLoaderForPath(path: string) {
    if (path.endsWith(".glb") || path.endsWith(".gltf")) {
      return new GLTFLoader();
    } else if (path.endsWith(".obj")) {
      return new OBJLoader();
    } else if (path.endsWith(".fbx")) {
      return new FBXLoader();
    }
    return null;
  }

  return model;
}
